﻿module BoardTool.List

open System
open System.Collections.Generic

open BoardTool.Tool
open BoardTool.Board
open BoardTool.Commands

type private ListCommand( dir ) =
    inherit MapDirCommand<(int * int) option>( dir )
    
    override this.Id = 
        sprintf "(list %s)" dir

    override this.processFile file =
        let size = ref None
        let hasUnrecognized = ref false
        parseBoardFile file
        |> Array.iter (function
            | Size( xSize, ySize ) ->
                size := Some (xSize, ySize)
            | Unrecognized s when s <> "" ->
                hasUnrecognized := true
            | _ -> ()
        )
        if !hasUnrecognized then None else !size
    
    override this.reduce results =
        seq { for file in results.Keys do yield (file, results.[file]) }
        |> Seq.groupBy snd
        |> Seq.sortBy 
            (fst >> function
            | Some (xSize, ySize) -> (xSize, ySize)
            | None -> (Int32.MaxValue, Int32.MaxValue)
            )
        |> Seq.iter 
            (fun (szOpt, filesSeq) ->
            match szOpt with
            | Some( xSize, ySize ) ->
                printfn ""
                printfn "%d x %d: %d boards" xSize ySize (Seq.length filesSeq)
                filesSeq |> Seq.iter (fst >> printfn "  %s")
            | None ->
                printfn ""
                printfn "Unknown size (POSSIBLY CORRUPTED): %d boards" (Seq.length filesSeq)
                filesSeq |> Seq.iter (fst >> printfn "  %s")
            )

let LIST_COMMAND_FACTORY =
    { new MapDirCommandFactory( "list", "lists boards in directory" ) with
        override this.createCommand( dir ) = 
            ListCommand( dir ) :> ICommand
    }